/*
 * Copyright 2011 Philippe Blanc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package me.l1k3.fx.client.channel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;

import me.l1k3.core.client.Core;
import me.l1k3.fx.client.channel.impl.OpenChannelImplJS;
import me.l1k3.fx.client.channel.inter.ChannelContext;
import me.l1k3.fx.client.channel.inter.ChannelDimension;
import me.l1k3.fx.client.channel.provider.DimensionProvider;
import me.l1k3.fx.client.channel.provider.DimensionProviderBlock;
import me.l1k3.fx.client.engine.inter.FXEngine;

public abstract class OpenChannel implements ChannelDimension {
	private DimensionProvider provider; 
	protected boolean backward;
	protected boolean horizontal;
	protected boolean vertical;
	
	//- - - factory
	
	public final static OpenChannel create(String type) {
	    if (type.equals(FXEngine.JS)) {
            return new OpenChannelImplJS();
        }
	    
	    return GWT.create(OpenChannel.class);
	}
	
	public final static OpenChannel horizontal(String type) {
		OpenChannel channel = create(type);
		channel.setHorizontal();
		
		return channel;
	}
	
	public final static OpenChannel vertical(String type) {
	    OpenChannel channel = create(type);
		channel.setVertical();
		
		return channel;
	}
	
	public final static OpenChannel both(String type) {
	    OpenChannel channel = create(type);
		channel.setHorizontal();
		channel.setVertical();
		
		return channel;
	}
	
    //- - -	
    
    public void setDimensionProvider(DimensionProvider provider) {
        this.provider = provider;
    }

    public void setHorizontal() {
	    horizontal = true;
	}
	
    public void setVertical() {
        vertical = true;
    }
	
	protected int getWidth() {
	    return provider.getWidth();
	}
	
	protected int getHeight() {
	    return provider.getHeight();
    }
	
    protected void setState(ChannelContext context) {
        if(horizontal)
        context.getStyle().setProperty("width", backward? "0px" : getWidth()+"px");
            
        if(vertical)
        context.getStyle().setProperty("height", backward? "0px" : getHeight()+"px");

        context.setVisible(!backward);
    }
	
    //- - -
    
    @Override
    public boolean isForward() {
        return !backward;
    }
	
    @Override
    public void init(ChannelContext context) {
        Element element = context.getElement();
        Style style = context.getStyle();
        style.setProperty("overflow", "hidden");    
        
        backward = (Core.getComputedStyleProperty(element, "visibility").equals("hidden") || Core.getComputedStyleProperty(element, "display").equals("none"));
 
        if(!backward) {
            if(horizontal && element.getOffsetWidth()==0) {
                backward = true;
            }
            else
            if(vertical && element.getOffsetHeight()==0) {
                backward = true;
            }
        }
            
        if(provider==null) {
            provider = new DimensionProviderBlock(context.getElement());
        }

        context.enableShowAndHide();
        setState(context);
    }
    
    @Override
    public final void toggle(ChannelContext context) {        
        backward = !backward;
        setState(context);
    }
    
    /*
    @Override
    public void start(ChannelContext context) { }
    */
    
    /*
    @Override
    public void update(ChannelContext context) { }
    */ 

	@Override
	public final void complete(ChannelContext context) {
	    toggle(context);
	}
}
